/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package productions;

import exceptions.ParserException;
import lexico.ErrorTable;
import lexico.SymbolTable;
import lexico.TokenClass;

/**
 *
 * @author maocleal
 */
public class CastProduction extends AbstractProductionRule {

    /**
     * Referencia estatica e privada
     */
    private static CastProduction instance = new CastProduction();

    /**
     * Construtor privado para o objeto nao ser instanciado em nenhum lugar alem
     * da classe atual
     */
    

    /**
     * Verifica se o objeto ja foi instanciado previamente. Se nao, instancia e
     * atribui aa referencia estatica.
     *
     * @return a referencia univoca do objeto
     */
    public static CastProduction getInstance() {
        return instance;
    }

    /**
     * Regra: cast : 'cast' '(' tipo_variavel (array)* ',' valor ')';
     * @return
     * @throws ParserException
     */
    public boolean analyze(SymbolTable st, ErrorTable et) throws ParserException {
        if (!basicParse(st, TokenClass.KEYWORD_CAST)) {
            return false;
        }

        if (!basicParse(st, TokenClass.DELIMITER_OPENING_PARENTHESIS)) {
            return skipUntilSynchronize(st, et, "Era esperado um '(' .");
        }

        if (!TipoVariavelProduction.getInstance().analyze(st, et)) {
            return skipUntilSynchronize(st, et, "Era esperado um Tipo.");
        }

        while (ArrayProduction.getInstance().analyze(st, et)) {
        }

        if (!basicParse(st, TokenClass.DELIMITER_COMMA)) {
            return skipUntilSynchronize(st, et, "Era esperado uma ','.");
        }

        if (!ValorProduction.getInstance().analyze(st, et)) {
            return skipUntilSynchronize(st, et, "Era esperado um valor.");
        }

        if (!basicParse(st, TokenClass.DELIMITER_CLOSING_PARENTHESIS)) {
            return skipUntilSynchronize(st, et, "Era esperado um ')'.");
        }

        return true;
    }

    @Override
    protected void populateFirst() {
        this.first.add(TokenClass.KEYWORD_CAST);
    }

    @Override
    protected void populateFollow() {
        //from fator follow
        follow.addAll(OpMultProduction.getInstance().first);
        follow.addAll(TermoProduction.getInstance().follow);
    }

}
